package com.zl.csMall.product.commodity.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zl.csMall.code.LoginCacheMap;
import com.zl.csMall.code.config.token.TokenTriggerAspect;
import com.zl.csMall.mine.favorites.service.FavoritesService;
import com.zl.csMall.mine.history.service.HistoryService;
import com.zl.csMall.mine.user.po.User;
import com.zl.csMall.product.commodity.po.Commodity;
import com.zl.csMall.product.commodity.service.CommodityService;
import com.zl.csMall.product.commodity.vo.CountVisitorsVo;
import com.zl.csMall.util.Util;
import com.zl.csMall.vo.ReturnModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @description: CommodityController
 * @author: ChenNing
 * @date 2025-10-20 10:39
 */
@CrossOrigin(origins = "*")
@Api(tags = "商品")
@RestController
@RequestMapping("csMall/product/commodity")
public class CommodityController {

    @Autowired
    private CommodityService commodityService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private FavoritesService favoritesService;

    private final LoginCacheMap loginCacheMap;

    public CommodityController(LoginCacheMap loginCacheMap) {
        this.loginCacheMap = loginCacheMap;
    }


    /**
     * @description: 根据分类查询商品
     * @param typeEnumId 分类枚举ID
     * @param isListed 是否上架（0：全部、1：上架、2：未上架）
     * @author ChenNing
     * @date: 2025-10-20 15:05
     */
    @ApiOperation(value = "根据分类查询商品列表", response = Commodity.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "typeEnumId", value = "分类枚举ID", required = true),
            @ApiImplicitParam(name = "isListed", value = "是否上架（0：全部、1：上架、2：未上架）"),
    })
    @CrossOrigin("*")
    @GetMapping("type/{typeEnumId}")
    public ReturnModel getCommodityByType(@PathVariable("typeEnumId") Long typeEnumId, @RequestParam(required = false) Integer isListed,
                                          @RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize){
        LambdaQueryWrapper<Commodity> commodityQuery = new LambdaQueryWrapper<>();
        commodityQuery.eq(Commodity::getTypeEnumId, typeEnumId);
        if (isListed != null && (isListed == 1 || isListed == 2)){
            commodityQuery.eq(Commodity::getIsListed, isListed);
        }
        Page<Map<String, Object>> commodityPage = commodityService.getSimplePage(commodityQuery, new Page<>(pageNum, pageSize));
        return new ReturnModel(commodityPage);
    }

    /**
     * @description: 获取全部商品信息
     * @param content 模糊查询（仅商品编号或名称）
     * @author ChenNing
     * @date: 2025-10-22 11:11
     */
    @ApiOperation(value = "查询全部商品", response = Commodity.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "content", value = "搜索内容（仅商品编号或名称）"),
            @ApiImplicitParam(name = "isListed", value = "是否上架（0：全部、1：上架、2：未上架）"),
    })
    @CrossOrigin("*")
    @GetMapping
    public ReturnModel getCommodityAll(@RequestParam(required = false) String content, @RequestParam(required = false) Integer isListed,
                                       @RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize){
        LambdaQueryWrapper<Commodity> commodityQuery = new LambdaQueryWrapper<>();
        if (!Util.isNullOrEmpty(content)){
            commodityQuery.like(Commodity::getNumber, content).or().like(Commodity::getName, content);
        }
        if (isListed != null && (isListed == 1 || isListed == 2)){
            commodityQuery.eq(Commodity::getIsListed, isListed);
        }
        Page<Map<String, Object>> commodityPage = commodityService.getSimplePage(commodityQuery, new Page<>(pageNum, pageSize));
        return new ReturnModel(commodityPage);
    }

    /**
     * @description: 根据商品ID查询商品
     * @param id 商品ID
     * @author ChenNing
     * @date: 2025-10-20 16:48
     */
    @ApiOperation(value = "根据ID查询商品", response = Commodity.class)
    @ApiImplicitParam(name = "id", value = "商品ID", required = true)
    @CrossOrigin("*")
    @GetMapping("{id}")
    public ReturnModel getById(@RequestHeader(value = "token", required = false) String token,
                               @PathVariable("id") Long id){
        Commodity commodity = commodityService.getCommodity(id);
        if (commodity == null){
            return new ReturnModel(false, "未查询到对应商品信息！");
        }

        if (!Util.isNullOrEmpty(token)){
            User user = loginCacheMap.getUser(token);
            if (user != null && user.getId() != 0){
                // 新增该商品浏览记录
                historyService.addHistory(user.getId(), id);
                // 判断该商品是否被该用户收藏
                boolean isFavorites = favoritesService.isExistence(user.getId(), id, false);
                commodity.setIsFavorites(isFavorites ? 1 : 2);
            }
        } else {
            commodity.setIsFavorites(2);
        }

        return new ReturnModel(commodity);
    }

    /**
     * @description: 添加商品
     * @author ChenNing
     * @date: 2025-10-20 10:43
     */
    @CrossOrigin("*")
    @ApiOperation(value = "添加商品 - 商家")
    @TokenTriggerAspect
    @PostMapping
    public ReturnModel addCommodity(@RequestHeader(required = false) String token,
                                    @Validated @RequestBody Commodity commodity){
        Date date = new Date();
        commodity.setId(Util.getUuId());
        commodity.setCreateDate(date);
        commodity.setUpdateDate(date);
        boolean result = commodityService.save(commodity);
        if (result){
            return new ReturnModel();
        }
        return new ReturnModel(false, "商品添加失败！");
    }

    /**
     * @description: 修改商品
     * @author ChenNing
     * @date: 2025-10-20 10:47
     */
    @CrossOrigin("*")
    @ApiOperation(value = "修改商品 - 商家")
    @TokenTriggerAspect
    @PutMapping
    public ReturnModel updateCommodity(@RequestHeader(required = false) String token,
                                       @RequestBody Commodity commodity){
        if (commodity == null || commodity.getId() == 0){
            return new ReturnModel(false, "商品ID不能为空！");
        }
        commodity.setUpdateDate(new Date());
        boolean result = commodityService.updateById(commodity);
        if (result){
            return new ReturnModel();
        }
        return new ReturnModel(false, "商品信息更新失败！");
    }

    /**
     * @description: 批量修改商品
     * @author ChenNing
     * @date: 2025-10-23 18:31
     */
    @CrossOrigin("*")
    @ApiOperation(value = "批量修改商品 - 商家")
    @TokenTriggerAspect
    @PutMapping("batch")
    public ReturnModel updateCommodityBatch(@RequestHeader(required = false) String token,
                                       @RequestBody List<Commodity> commodityList){
        if (commodityList == null || commodityList.size() < 1){
            return new ReturnModel(false, "商品ID不能为空！");
        }
        Date date = new Date();
        int index = 0;
        for (Commodity commodity : commodityList){
            if (commodity == null || commodity.getId() == 0){
                return new ReturnModel(false, "商品ID不能为空！");
            }
            commodity.setUpdateDate(date);
            commodityList.set(index, commodity);
            index++;
        }
        boolean result = commodityService.updateBatchById(commodityList);
        if (result){
            return new ReturnModel();
        }
        return new ReturnModel(false, "商品信息更新失败！");
    }

    /**
     * @description: 删除商品
     * @param id 商品ID
     * @author ChenNing
     * @date: 2025-10-20 10:51
     */
    @CrossOrigin("*")
    @ApiOperation(value = "根据ID删除商品 - 商家")
    @TokenTriggerAspect
    @DeleteMapping
    public ReturnModel deleteCommodity(@RequestHeader(required = false) String token,
                                       @RequestParam("id") Long id){
        if (Util.isNullOrEmpty(id)){
            return new ReturnModel(false, "商品ID为空！");
        }
        boolean result = commodityService.deleteById(id);
        if (result){
            return new ReturnModel();
        }
        return new ReturnModel(false, "商品删除失败！");
    }

    /**
     * @description: 根据用户ID查询收藏商品
     * @author ChenNing
     * @date: 2025-10-21 14:20
     */
    @ApiOperation(value = "查询用户收藏商品", response = Commodity.class)
    @CrossOrigin("*")
    @TokenTriggerAspect
    @GetMapping("favorites")
    public ReturnModel getFavoritesByUserId(@RequestHeader(required = false) String token,
                                            @RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize){
        User user = loginCacheMap.getUser(token);

        Page<Map<String, Object>> favoritesCommodityPage = commodityService.getFavoritesByUserId(user.getId(), new Page<>(pageNum, pageSize));
        return new ReturnModel(favoritesCommodityPage);
    }

    /**
     * @description: 查询用户历史浏览商品列表
     * @author ChenNing
     * @date: 2025-10-21 13:40
     */
    @ApiOperation(value = "查询用户浏览记录", response = Commodity.class)
    @CrossOrigin("*")
    @TokenTriggerAspect
    @GetMapping("history")
    public ReturnModel getByUserId(@RequestHeader(required = false) String token,
                                   @RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize){
        User user = loginCacheMap.getUser(token);

        Page<Map<String, Object>> historyCommodityPage = commodityService.getHistoryByUserId(user.getId(), new Page<>(pageNum, pageSize));
        return new ReturnModel(historyCommodityPage);
    }

    /**
     * @description: 查询商品浏览数据（按商品历史浏览量从大到小排列）
     * @author ChenNing
     * @date: 2025-10-21 15:28
     */
    @ApiOperation(value = "查询商品浏览数据 - 商家", response = CountVisitorsVo.class)
    @CrossOrigin("*")
    @TokenTriggerAspect
    @GetMapping("history/countVisit")
    public ReturnModel countVisitors(@RequestHeader(required = false) String token,
                                     @RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize){
        Page<CountVisitorsVo> page = commodityService.countVisitors(new Page<>(pageNum, pageSize));
        return new ReturnModel(page);
    }

}
